//
//  PLHttpTools.m
//  PointLegend
//
//  Created by 黄卫 on 17/3/1.
//  Copyright © 2017年 huangwei. All rights reserved.
//

#import "TYHttpTools.h"
#import "TYFMDBTool.h"
#import "Reachability.h"
#import "TYHttpError.h"

typedef enum : NSUInteger {
    RequestStoreCacheData,  //缓存网络数据
    RequestIgnoreCacheData, //忽略网络缓存
} GJRequestCachePolicy;//是否需要缓存网络数据

typedef enum : NSUInteger {
    RequestType_get,    //get请求
    RequestType_post,   //post请求
} GJRequestServerType;//网络请求方式


@implementation TYHttpTools


static AFHTTPSessionManager *mgr_;

/**
 *  常见创建请求管理者
 */
+ (void)initialize
{
    mgr_ = [AFHTTPSessionManager manager];
    mgr_.responseSerializer = [AFJSONResponseSerializer serializer];
    mgr_.requestSerializer = [AFJSONRequestSerializer serializer];
    mgr_.requestSerializer.timeoutInterval = 30;
    mgr_.responseSerializer.acceptableContentTypes = [NSSet setWithObjects:@"text/html",@"application/json",nil];

    //设置请求cookie
    [self loadCookies];
}

#pragma mark - 包装每个接口缓存数据的key

/**
 *  根据接口参数包装缓存数据key
 */
+(NSString *)getCacheKeyByRequestUrl:(NSString *)urlString parameter:(NSDictionary *)parameter
{
    NSString * key = @"";
    if (urlString && [urlString isKindOfClass:[NSString class]]) {
        key = urlString;
    }
    if (parameter && [parameter isKindOfClass:[NSDictionary class]]) {
        NSArray * dickeys = [parameter allKeys];
        for (NSString * dickey in dickeys) {
            NSString * valus = [parameter objectForKey:dickey];
            key = [NSString stringWithFormat:@"%@%@%@",key,dickey,valus];
        }
    }
    return key;
}


 
#pragma mark - 保存Cookies方法
+ (void)saveCookies
{
    NSData *cookiesData = [NSKeyedArchiver archivedDataWithRootObject: [[NSHTTPCookieStorage sharedHTTPCookieStorage] cookies]];
    SaveUserDefault(RequestHeadCookieKey, cookiesData);
}

#pragma mark - 加载Cookies方法
+ (void)loadCookies
{
    NSData *cookieData = GetUserDefault(RequestHeadCookieKey);
    if (cookieData) {
        NSArray *cookieArr = [NSKeyedUnarchiver unarchiveObjectWithData:cookieData];
        NSHTTPCookieStorage *cookieStorage = [NSHTTPCookieStorage sharedHTTPCookieStorage];
        for (NSHTTPCookie *cookie in cookieArr) {
            [cookieStorage setCookie: cookie];
        }
    }
}


/**
 *  http 请求方法封装
 *
 *  @param url     要请求的url
 *  @param params  参数
 *  @param success 请求成功执行的block
 *  @param failure 请求失败执行的block
 *  @param requestType 请求方式(get/post)
 *  @param cachePolicy 网络请求是否需要缓存
 */
+ (NSURLSessionDataTask *)url:(NSString *)url
                       params:(NSDictionary *)params
                 success:(ReturnValueBlock)success
                 failure:(ErrorCodeBlock)failure
                  requestType:(GJRequestServerType)type
                  cachePolicy:(GJRequestCachePolicy)cachePolicy
{
    //获取网络缓存Key
    NSString *cachekey = nil;
    if (cachePolicy == RequestStoreCacheData) {
        cachekey = [self getCacheKeyByRequestUrl:url parameter:params];
        NSDictionary *cacheDic = [TYFMDBTool getObjectById:cachekey fromTable:JsonDataTableType];
        NSMutableDictionary *mDict = cacheDic.mutableCopy;
        mDict[@"fromCache"]=@1;
        if (cacheDic) {
            success(mDict);
        }
    }
    
    //网络不正常直接诶返回失败
    if (![Reachability isInternetConnection]) {
        if (failure) {
            TYHttpError *error = [TYHttpError getTYHttpErrorByServerError:nil serverCode:GJNoInterneErrorCode serverTip:nil];
            failure(error);
        }
        return nil;
    }
    
    //成功回调
    void(^sucBackBlock)(id responseObject) = ^(id responseObject){
        //防止页面上有其他弹框
        [MBProgressHUD hideLoadingFromWindow];
        
        NSInteger code = [responseObject[@"code"] integerValue];
        if (code == 0 || code == 200)
        {
            NSLog(@"请求参数= %@\n请求地址= %@\n成功返回= %@",params,url,responseObject);
            /** <1>.回调页面请求 */
            if (success) {
                success(responseObject);
            }
            
            /** <2>.是否需要缓存 */
            if (cachePolicy == RequestStoreCacheData) {
                NSData  *jsonData = [NSJSONSerialization dataWithJSONObject:responseObject options:NSJSONWritingPrettyPrinted error:nil];
                NSString *jsonStr = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding];
                NSData * data = [jsonStr dataUsingEncoding:NSUTF8StringEncoding];
                if (data) { //保存数据到数据库
                    [TYFMDBTool saveDataToDB:data byObjectId:cachekey toTable:JsonDataTableType];
                }
            }
            
            /** <3>.如果是登录或入驻接口, 就保存登录的Cookie */
            if ([url isEqualToString:API(Url_shopLogin)] || [url isEqualToString:API(Url_register)]) {
                [TYHttpTools saveCookies];
            }
            
        } else {
            
            NSLog(@"请求参数= %@\n请求地址= %@\n 失败返回= %@",params,url,responseObject);
            if (failure) {
                TYHttpError *httpError = [TYHttpError getTYHttpErrorByServerError:nil serverCode:code serverTip:responseObject[@"msg"]];
                failure(httpError);
            }
        }
    };
    
    //失败回调
    void (^failBackBlock)(NSError *) = ^(NSError *error){
        //防止页面上有其他弹框
        [MBProgressHUD hideLoadingFromWindow];
        
        NSLog(@"请求参数= %@\n请求地址= %@\n 失败返回= %@",params,url,error);
        if (failure) {
            failure([TYHttpError getTYHttpErrorByServerError:error serverCode:GJNotErrorCode serverTip:nil]);
        }
    };
    
    
    //根据网络请求方式发请求
    if (type == RequestType_get) { //get请求
        
        return [mgr_ GET:url
              parameters:params
                progress:nil
                 success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {
            sucBackBlock(responseObject);
                     
            NSLog(@"Get Url %@",task.response.URL.absoluteString);
            
        } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
            failBackBlock(error);
        }];
        
    } else if(type == RequestType_post){ //post请求
        
        return [mgr_ POST:url
               parameters:params
                 progress:nil
                  success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {
                      
            sucBackBlock(responseObject);
            
        } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
            failBackBlock(error);
        }];
    }
    
    return nil;
}


#pragma mark - ========== http get请求入口 ==========


/**
 *  get请求不需要缓存
 */
+ (NSURLSessionDataTask *)getRequestNotNeedCache:(NSString *)url
                                          params:(NSDictionary *)params
                            success:(ReturnValueBlock)block
                                failure:(ErrorCodeBlock)failure
{
    return [self url:url params:params
        success:block
        failure:failure
         requestType:RequestType_get
         cachePolicy:RequestIgnoreCacheData];
}


/**
 *  get请求需要缓存
 */
+ (NSURLSessionDataTask *)getRequestNeedCache:(NSString *)url
                                       params:(NSDictionary *)params
                         success:(ReturnValueBlock)block
                             failure:(ErrorCodeBlock)failure
{
    return [self url:url
              params:params
        success:block
        failure:failure
         requestType:RequestType_get
         cachePolicy:RequestStoreCacheData];
}


#pragma mark ========== http post请求入口 ==========

/**
 *  post请求不需要缓存
 */
+ (NSURLSessionDataTask *)post:(NSString *)url
                        params:(NSDictionary *)params
          success:(ReturnValueBlock)block
              failure:(ErrorCodeBlock)failure
{
    return [self url:url
              params:params
        success:block
        failure:failure
         requestType:RequestType_post
         cachePolicy:RequestIgnoreCacheData];
}


#pragma mark ========== http 上传文件请求入口 ==========

/**
 *  上传文件
 */
+ (NSURLSessionDataTask *)post:(NSString *)url
                        params:(NSDictionary *)params
                     imageData:(NSData *)data
          success:(ReturnValueBlock)block
              failure: (ErrorCodeBlock) failure
{
    //网络不正常直接诶返回失败
    if (![Reachability isInternetConnection]) {
        if (failure) {
            TYHttpError *error = [TYHttpError getTYHttpErrorByServerError:nil serverCode:GJNoInterneErrorCode serverTip:nil];
            failure(error);
        }
        return nil;
    }
    
    return [mgr_ POST:url parameters:params constructingBodyWithBlock:^(id<AFMultipartFormData>  _Nonnull formData) {
        [formData appendPartWithFileData:data name:@"file" fileName:@"file.png" mimeType:@"image/jpeg"];
        
    } progress:nil success:^(NSURLSessionDataTask * _Nonnull task, id  _Nonnull responseObject) {
        NSInteger code = [responseObject[@"code"] integerValue];
        if (code == 0) {
            NSLog(@"请求参数= %@\n请求地址= %@\n成功返回= %@",params,url,responseObject);
            if (block) {
                block(responseObject);
            }
        } else {
            NSLog(@"请求参数= %@\n请求地址= %@\n 失败返回= %@",params,url,responseObject);
            if (failure) {
                TYHttpError *httpError = [TYHttpError getTYHttpErrorByServerError:nil serverCode:code serverTip:responseObject[@"msg"]];
                failure(httpError);
            }
        }
    } failure:^(NSURLSessionDataTask * _Nonnull task, NSError * _Nonnull error) {
        NSLog(@"请求参数= %@\n请求地址= %@\n 失败返回= %@",params,url,error);
        if (failure) {
            TYHttpError *httpError = [TYHttpError getTYHttpErrorByServerError:error serverCode:GJNotErrorCode serverTip:nil];
            failure(httpError);
        }
    }];
}


@end
